package com.shigu.example.test.daifa.service;

import org.apache.commons.lang3.StringUtils;
import com.opentae.core.mybatis.example.MultipleExample;
import com.opentae.core.mybatis.example.MultipleExampleBuilder;
import com.opentae.core.mybatis.mapper.MultipleMapper;
import com.opentae.data.mall.beans.*;
import com.opentae.data.mall.examples.ItemProductExample;
import com.opentae.data.mall.examples.ItemProductSkuExample;
import com.opentae.data.mall.interfaces.*;
import com.opentae.data.xb.beans.DaifaAfterSale;
import com.opentae.data.xb.beans.DaifaAfterSaleSub;
import com.opentae.data.xb.interfaces.DaifaAfterSaleMapper;
import com.opentae.data.xb.interfaces.DaifaAfterSaleSubMapper;
import com.shigu.example.test.daifa.vo.DaifaOrderVO;
import com.shigu.example.test.daifa.vo.DaifaTradeVO;
import com.shigu.main4.common.util.BeanMapper;
import com.shigu.main4.order.enums.OrderStatus;
import com.shigu.main4.order.enums.OrderType;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by sean on 2017-08-30-0030.
 */
@Service
public class TransformService {


    @Autowired
    public DaifaAfterSaleMapper xbAfterSaleMapper;

    @Autowired
    public DaifaAfterSaleSubMapper xbAfterSaleSubMapper;

    @Autowired
    public com.shigu.main4.order.services.ItemOrderService itemOrderService;

    @Autowired
    public ItemOrderSubMapper itemOrderSubMapper;

    @Autowired
    public ItemOrderServiceMapper itemOrderServiceMapper;

    @Autowired
    public ItemOrderMapper itemOrderMapper;

    @Autowired
    public ItemOrderLogisticsMapper itemOrderLogisticsMapper;

    @Autowired
    public ItemProductMapper itemProductMapper;

    @Autowired
    public OrderPayApplyMapper orderPayApplyMapper;

    @Autowired
    public ItemProductSkuMapper itemProductSkuMapper;

    @Resource(name = "tae_mall_multipleMapper")
    public MultipleMapper multipleMapper;

    @Transactional(rollbackFor = Exception.class)
    public void createOrder(DaifaTradeVO v) {
        ItemOrder order = new ItemOrder();
        OrderType orderType = OrderType.XZ;
        if (v.getTaobaoTid() != null) {
            orderType = OrderType.TB;
            order.setOuterId(v.getTaobaoTid());
        }
        order.setOid(itemOrderService.idGenerator(orderType));
        order.setType(orderType.type);
        order.setDisenable(false);
        order.setSenderId(999999990L);
        order.setOrderStatus(tradeStatus(v.getTradeStatus()));// 待发状态最终只有已发，需判断支付日期，距离今天15天以上默认完成
        order.setCreateTime(v.getCreateTime());
        if (v.getMark() != null && v.getMark().length() > 50) {
            v.setMark(v.getMark().substring(0, 50));
        }
        order.setMark(v.getMark());
        order.setUserId(v.getUserId());
        order.setSendTime(v.getSendTime());
        Date finishTime;
        Date now=new Date();
        if (order.getOrderStatus() == OrderStatus.SELLER_SENDED_GOODS.status
                && (finishTime = DateUtils.addDays(v.getPayTime(), 15)).before(now)) {
            order.setOrderStatus(OrderStatus.TRADE_FINISHED.status);
            order.setFinishTime(finishTime);
        }
        List<DaifaOrderVO> orders = v.getOrders();
        DaifaOrderVO daifaOrderVO = orders.get(0);
        order.setWebSite(daifaOrderVO.getWebSite().replace("_xb", ""));
        if (StringUtils.isEmpty(order.getWebSite())) {
            order.setWebSite("hz");
        }
        if (orders.size() == 1) {
            if (daifaOrderVO.getTitle() != null && daifaOrderVO.getTitle().length() > 45) {
                daifaOrderVO.setTitle(daifaOrderVO.getTitle().substring(0, 45));
            }
            order.setTitle(daifaOrderVO.getTitle());
        } else if (orders.size() > 1) {
            order.setTitle("代发多单");
        }
        order.setTotalFee(parseMoney(v.getTotalFee()));
        order.setPayedFee(order.getTotalFee());
        order.setRefundFee(0L);

        itemOrderMapper.insertSelective(order);

        //添加物流信息
        Long logisticsId = addLogistics(order.getOid(), v);

        // 添加支付信息
        addPayInfo(order.getOid(), v);

        // 添加子单信息
        Long refundFee = addSubOrders(order.getOid(), logisticsId, v);
        if (refundFee > 0) {
            order.setRefundFee(refundFee);
            itemOrderMapper.updateByPrimaryKeySelective(order);
        }
    }

    public ItemProductInfo generatorItemProduct(DaifaOrderVO dov, String color, String size) {
        Long goodsId = dov.getGoodsId();
        ItemProductExample productExample = new ItemProductExample();
        productExample.and().andGoodsIdEqualTo(goodsId);
        ItemProductSkuExample skuExample = new ItemProductSkuExample();
        skuExample.and().andColorEqualTo(color);
        skuExample.and().andSizeEqualTo(size);
        MultipleExample build = MultipleExampleBuilder.from(productExample).innerJoin(skuExample).on(productExample.and().equalTo(ItemProductExample.pid, ItemProductSkuExample.pid)).build();

        List<ItemProductInfo> itemProductInfos = multipleMapper.selectFieldsByMultipleExample(build, ItemProductInfo.class);
        ItemProductInfo info;

        if (!itemProductInfos.isEmpty()) {
            info = itemProductInfos.get(0);
        } else {
            ItemProduct product = new ItemProduct();
            product.setGoodsId(goodsId);
            product = this.itemProductMapper.selectOne(product);
            if(product == null) {
                product = BeanMapper.map(dov, ItemProduct.class);
                product.setShopId(dov.getStoreId());
                product.setPrice(parseMoney(dov.getSinglePiPrice()));
                product.setGoodsNo(dov.getGoodsCode());
                product.setPicUrl(dov.getPicPath());
                product.setWeight(1000L);
                product.setFloor(dov.getFloorName());
                product.setShopNum(dov.getStoreNum());
                this.itemProductMapper.insertSelective(product);
            }

            ItemProductSku sku = new ItemProductSku();
            sku.setPid(product.getPid());
            sku.setColor(color);
            sku.setSize(size);
            this.itemProductSkuMapper.insertSelective(sku);
            info = new ItemProductInfo();
            info.setPid(product.getPid());
            info.setSkuId(sku.getSkuId());
        }
        return info;
    }

    public Long addSubOrders(final Long oid, final Long logisticsId, DaifaTradeVO v) {

        Long refundFee = 0L;

        Long dfTradeId = v.getDfTradeId();
        DaifaAfterSale sale = new DaifaAfterSale();
        sale.setDfTradeId(dfTradeId);
        sale = xbAfterSaleMapper.selectOne(sale);

        Map<Long, DaifaAfterSaleSub> afterSaleGroup = new HashMap<>();
        if (sale != null) {
            DaifaAfterSaleSub saleSub = new DaifaAfterSaleSub();
            saleSub.setDfTradeId(dfTradeId);
            saleSub.setAfterSaleId(sale.getAfterSaleId());
            afterSaleGroup.putAll(xbAfterSaleSubMapper.select(saleSub).stream().collect(Collectors.toMap(DaifaAfterSaleSub::getDfOrderId, e -> e)));
        }

        // 处理子单
        for (DaifaOrderVO dov : v.getOrders()) {
            if (dov == null || dov.getPropStr() == null || dov.getMarketId() == null
                    || dov.getStoreId() == null) {
                continue;
            }
            if (dov.getGoodsId() == null) {
                dov.setGoodsId(-1L);
            }

            if (StringUtils.isEmpty(dov.getTitle())) {
                dov.setTitle("代发订单");
            }
            if (StringUtils.isEmpty(dov.getFloorName())) {
                dov.setFloorName(getFloor(dov.getFloorId()));
            }
            if (StringUtils.isEmpty(dov.getWebSite())) {
                dov.setWebSite("hz");
            }
            if (dov.getFloorId() == null) {
                ShiguMarket f = new ShiguMarket();
                f.setParentMarketId(dov.getMarketId());
                List<ShiguMarket> select = shiguMarketMapper.select(f);
                if (select.isEmpty()) {
                    continue;
                }
                dov.setFloorId(select.get(0).getMarketId());
            }
            String[] props = dov.getPropStr().split(":");
            String color = props[0];
            String size = props[1];
            ItemOrderSub orderSub = new ItemOrderSub();
            orderSub.setOid(oid);
            ItemProductInfo itemProduct = generatorItemProduct(dov, color, size);
            orderSub.setPid(itemProduct.getPid());
            orderSub.setSkuId(itemProduct.getSkuId());
            orderSub.setNum(dov.getGoodsNum());
            orderSub.setShouldPayMoney(parseMoney(dov.getTotalFee()));
            orderSub.setRefundMoney(parseMoney(dov.getReturnGoodsFee()));
            orderSub.setStatus(0);
            String mark = dov.getMark();
            if (mark != null) {
                for (String s : mark.split("@@")) {
                    if (s.startsWith("买家备注:")) {
                        orderSub.setMark(s.replace("买家备注:", ""));
                        if (orderSub.getMark().length() > 50) {
                            orderSub.setMark(orderSub.getMark().substring(0,50));
                        }
                    }
                }
            }
            orderSub.setLogisticsId(logisticsId);
            orderSub.setGoodsId(dov.getGoodsId());
            orderSub.setPicUrl(dov.getPicPath());
            orderSub.setWebSite(dov.getWebSite().replace("_xb", ""));
            if (dov.getTitle() != null && dov.getTitle().length() > 45) {
                dov.setTitle(dov.getTitle().substring(0, 45));
            }
            orderSub.setTitle(dov.getTitle());
            orderSub.setPrice(parseMoney(dov.getSinglePiPrice()));
            orderSub.setWeight(1000L);
            orderSub.setSize(size);
            orderSub.setColor(color);
            orderSub.setRefundMoney(0L);
            orderSub.setGoodsNo(dov.getGoodsCode());
            orderSub.setMarketId(dov.getMarketId());
            orderSub.setMarketName(dov.getMarketName());
            orderSub.setFloorId(dov.getFloorId());
            orderSub.setFloor(dov.getFloorName());
            orderSub.setShopNum(dov.getStoreNum());
            orderSub.setShopId(dov.getStoreId());
            itemOrderSubMapper.insertSelective(orderSub);

            //添加代发服务
            addService(oid, orderSub.getSoid(), parseMoney(dov.getTotalDaifaFee()));

            // 处理退款

            if (dov.getRefundStatus() != null) {
                ItemOrderRefund refund = new ItemOrderRefund();
                refund.setOid(oid);
                refund.setSoid(orderSub.getSoid());
                refund.setType(1);
                refund.setRefundMoney(orderSub.getPrice() * orderSub.getNum());
                refund.setHopeMoney(refund.getRefundMoney());
                refund.setNumber(orderSub.getNum());
                refund.setStatus(dov.getRefundStatus() == 1 ? 0 : 2);
                refund.setUserApply(true);
                refund.setReason("");
//                refund.setBuyerReturnTime();
                itemOrderRefundMapper.insertSelective(refund);

                refundFee += refund.getRefundMoney();

                ItemOrderSub itemOrderSub = new ItemOrderSub();
                itemOrderSub.setSoid(orderSub.getSoid());
                itemOrderSub.setRefundMoney(refund.getRefundMoney());
                itemOrderSubMapper.updateByPrimaryKeySelective(itemOrderSub);
            }

            // 处理售后
            DaifaAfterSaleSub saleSub;
            if (sale != null && (saleSub = afterSaleGroup.get(dov.getDfOrderId())) != null) {
                ItemOrderRefund refund = new ItemOrderRefund();
                refund.setOid(oid);
                refund.setSoid(orderSub.getSoid());
                refund.setType(sale.getAfterType() + 1);
                refund.setUserApply(true);
                refund.setRefundMoney(0L);
                refund.setHopeMoney(0L);
                refund.setNumber(saleSub.getGoodsNum());
                refund.setBuyerCourier(saleSub.getReturnPostCode());
                refund.setBuyerReturnTime(saleSub.getSendTime());
                Integer returnChangeStatus;
                if (refund.getType() == 2) {
                    refund.setRefundMoney(orderSub.getPrice() * saleSub.getGoodsNum());
                    refund.setHopeMoney(refund.getRefundMoney());
                    returnChangeStatus = saleSub.getReturnStatus();

                    refundFee += refund.getRefundMoney();
                    orderSub = itemOrderSubMapper.selectByPrimaryKey(orderSub.getSoid());
                    ItemOrderSub itemOrderSub = new ItemOrderSub();
                    itemOrderSub.setSoid(orderSub.getSoid());
                    itemOrderSub.setRefundMoney(orderSub.getRefundMoney() + refund.getRefundMoney());
                    itemOrderSubMapper.updateByPrimaryKeySelective(itemOrderSub);
                } else {
                    returnChangeStatus = saleSub.getChangeStatus();
                }
                if (returnChangeStatus == null) {
                    returnChangeStatus = 0;
                }
                switch (returnChangeStatus) {
                    case 4:case 3:case 7:
                        returnChangeStatus = 2;
                        break;
                    case 5:case 6:case 8:
                        returnChangeStatus = 4;
                        break;
                    default:
                        returnChangeStatus = 0;
                }
                refund.setStatus(returnChangeStatus);
                itemOrderRefundMapper.insertSelective(refund);
            }
        }
        return refundFee;
    }

    @Autowired
    public ItemOrderRefundMapper itemOrderRefundMapper;

    @Autowired
    public OrderPayMapper orderPayMapper;

    @Autowired
    public OrderPayRelationshipMapper orderPayRelationshipMapper;

    @Autowired
    public ShiguMarketMapper shiguMarketMapper;

    public static Map<Long, String> floorCache = new HashMap<>();

    public String getFloor(Long floorId) {
        String s = floorCache.get(floorId);
        if (s == null) {
            ShiguMarket shiguMarket = shiguMarketMapper.selectByPrimaryKey(floorId);
            s = "1F";
            if (shiguMarket != null) {
                s = shiguMarket.getMarketName();
            }
            floorCache.put(floorId, s);
        }
        return s;
    }

    public void addPayInfo(Long oid, DaifaTradeVO v) {
        OrderPayApply apply = new OrderPayApply();
        apply.setOid(oid);
        apply.setCreateTime(v.getPayTime());
        apply.setMoney(parseMoney(v.getTotalFee()));
        apply.setPayFor(1);
        apply.setType(3);
        apply.setUserId(v.getUserId());
        orderPayApplyMapper.insertSelective(apply);

        OrderPay pay = new OrderPay();
        pay.setApplyId(apply.getApplyId());
        pay.setPayFor(1);
        pay.setType(3);
        pay.setMoney(apply.getMoney());
        pay.setCreateTime(apply.getCreateTime());
//        pay.setRefundMoney(parseMoney(v.g));
        pay.setOuterPid(v.getDfTradeId().toString());
        pay.setOuterPuser(v.getReceiverName());
        orderPayMapper.insertSelective(pay);

        OrderPayRelationship relationship = new OrderPayRelationship();
        relationship.setOid(oid);
        relationship.setPayId(pay.getPayId());
        orderPayRelationshipMapper.insertSelective(relationship);
    }

    public void addService(Long oid, Long soid, Long money) {
        com.opentae.data.mall.beans.ItemOrderService itemOrderService
                = new com.opentae.data.mall.beans.ItemOrderService();
        itemOrderService.setName("代发服务");
        itemOrderService.setMoney(money);
        itemOrderService.setServiceId(1L);
        itemOrderService.setOid(oid);
        itemOrderService.setRefundMoney(0L);
        itemOrderService.setSoid(soid);
        itemOrderServiceMapper.insertSelective(itemOrderService);
    }

    public Long addLogistics(Long oid, DaifaTradeVO v) {
        ItemOrderLogistics logistics = new ItemOrderLogistics();
        logistics.setOid(oid);
        logistics.setMoney(parseMoney(v.getPostFee()));
        logistics.setName(v.getReceiverName());
        logistics.setCourierNumber(v.getPostCode());
        logistics.setTelephone(v.getReceiverMobile());
        logistics.setZipCode(v.getReceiverZip());
        if (v.getPostName().startsWith("邮")) {
            v.setPostName("ems");
        }
        logistics.setCompanyId(getCompanyId(v.getPostName().substring(0, 2)));
        String fullAddress = v.getReceiverAddress();
        String[] addr = fullAddress.split(" ");
        if (addr.length > 2) {
            logistics.setProvId(getProvId(addr[0].substring(0, 2)));
            logistics.setCityId(getCityId(addr[1].substring(0, 2)));
            if (addr[2].length() > 2) {
                logistics.setTownId(getTownId(addr[2].substring(0, 2), logistics.getCityId()));
            }
            fullAddress = "";
            for (int i = 2; i < addr.length; i++) {
                fullAddress += addr[i];
            }
        }
        logistics.setAddress(fullAddress);

        itemOrderLogisticsMapper.insertSelective(logistics);
        return logistics.getId();
    }

    public int tradeStatus(int status) {
        int orderStatus;
        switch (status) {
            case -1:
            case 0:
                orderStatus = OrderStatus.WAIT_BUYER_PAY.status;
                break;
            case 1:
                orderStatus = OrderStatus.TRADE_CLOSED.status;
                break;
            case 2:
            case 3:
                orderStatus = OrderStatus.BUYER_PAYED.status;
                break;
            case 5:
                orderStatus = OrderStatus.SELLER_SENDED_GOODS.status;
                break;
            default:
                orderStatus = 0;
        }
        return orderStatus;
    }

    public Long parseMoney(String price) {
        if (price == null) {
            return 0L;
        }
        return ((Double) (Double.valueOf(price) * 100)).longValue();
    }

    Map<String, Long> provMap;
    Map<String, Long> cityMap;
    Map<String, List<OrderTown>> townMap;
    Map<String, Long> companyMap;

    @Autowired
    OrderProvMapper orderProvMapper;

    @Autowired
    OrderCityMapper orderCityMapper;

    @Autowired
    OrderTownMapper orderTownMapper;

    @Autowired
    ExpressCompanyMapper expressCompanyMapper;

    @PostConstruct
    public void init() {
        provMap = orderProvMapper.select(new OrderProv()).stream().collect(Collectors.toMap(OrderProv::getProvName, OrderProv::getProvId));
        cityMap = orderCityMapper.select(new OrderCity()).stream().collect(Collectors.toMap(OrderCity::getCityName, OrderCity::getCityId));
        townMap = orderTownMapper.select(new OrderTown()).stream().collect(Collectors.groupingBy(OrderTown::getTownName));
        companyMap = expressCompanyMapper.select(new ExpressCompany()).stream().collect(Collectors.toMap(ExpressCompany::getExpressName, ExpressCompany::getExpressCompanyId));
    }

    public Long getProvId(String prov) {
        return getSomeId(prov, provMap);
    }

    public Long getCityId(String city) {
        return getSomeId(city, cityMap);
    }

    public Long getTownId(String town, Long cityId) {
        for (Map.Entry<String, List<OrderTown>> entry : townMap.entrySet()) {
            if (entry.getKey().startsWith(town.toUpperCase())) {
                for (OrderTown orderTown : entry.getValue()) {
                    if (cityId.equals(orderTown.getCityId())) {
                        return orderTown.getTownId();
                    }
                }
            }
        }
        return null;
    }

    public Long getCompanyId(String company) {
        return getSomeId(company, companyMap);
    }

    public Long getSomeId(String prov, Map<String, Long> data) {
        Long defValue = null;
        for (Map.Entry<String, Long> entry : data.entrySet()) {
            if (defValue == null) {
                defValue = entry.getValue();
            }
            if (entry.getKey().startsWith(prov)) {
                return entry.getValue();
            }
        }
        return defValue;
    }
}
